【アップデート】Step FunctionsのワークフローがSAM/CFnテンプレートにエクスポート可能になりました

【アップデート】Step FunctionsのワークフローがSAM/CFnテンプレートにエクスポート可能になりました

Clock Icon2024.11.15

リテールアプリ共創部@大阪の岩田です。

2024/11/14付けのアップデートでStep FunctionsのワークフローがSAMテンプレートもしくはCloudFormationのテンプレートにエクスポートできるようになりました!!

https://aws.amazon.com/jp/about-aws/whats-new/2024/11/infrastructure-code-template-generation-aws-step-functions/

ワークフローを構築するテンプレートを1から手で書くのは大変ですが、今後はマネコンからGUI操作で作ったワークフローをテンプレートとしてエクスポートして微調整するという方法が取れるようになります。これは熱い!

やってみる

さっそくワークフローのエクスポートを試してみます。以下のブログ執筆時に構築したワークフローがあったので、これをエクスポートしてみます。

https://dev.classmethod.jp/articles/create-blog-review-api-with-bedrock/

マネコンにアクセスすると「CloudFormation または SAM テンプレートにエクスポート」というメニューが増えていることが分かります。

ワークフローをエクスポートするメニュー

メニューを選択すると次はテンプレートの形式を選択するためのダイアログが表示されます。

SAMを選択した場合は以下のようなオプションが指定できます。

SAMにエクスポートする際のオプション

CFnを選択した場合のオプションは以下です。SAMで指定可能なオプションに加えてファイル形式をJSONかYAMLか指定できるようになっています。

CFnにエクスポートする際のオプション

今回はSAMを選択して「ダウンロード」をクリックしました。

エクスポートされたSAMテンプレート

出力されたテンプレートは以下の通りです。

Transform: AWS::Serverless-2016-10-31
Resources:
  StateMachine71095795:
    Type: AWS::Serverless::StateMachine
    Properties:
      Definition:
        Comment: (prd) DevIOのブログをレビューするステートマシン
        StartAt: Parallel
        States:
          Parallel:
            Type: Parallel
            End: true
            Branches:
              - StartAt: ReviewBlogMediaPolicy
                States:
                  ReviewBlogMediaPolicy:
                    Type: Task
                    Resource: arn:aws:states:::bedrock:invokeModel
                    Parameters:
                      ModelId: ${bedrockinvokeModel_ModelId_53adbc72}
                      Body:
                        anthropic_version: bedrock-2023-05-31
                        max_tokens: 2000
                        system: >
                          メディアポリシーチェック用のプロンプト
                          ...略

                          ```
                        messages:
                          - role: user
                            content:
                              - type: text
                                text.$: $.article
                        temperature: 0
                    OutputPath: $.Body.content[0].text
                    End: true
              - StartAt: ReviewBlogTypo
                States:
                  ReviewBlogTypo:
                    Type: Task
                    Resource: arn:aws:states:::bedrock:invokeModel
                    Parameters:
                      ModelId: ${bedrockinvokeModel_ModelId_49ef62c9}
                      Body:
                        anthropic_version: bedrock-2023-05-31
                        max_tokens: 2000
                        system: |
                          タイポチェック用のプロンプト
                          ...略
                        messages:
                          - role: user
                            content:
                              - type: text
                                text.$: $.article
                        temperature: 0
                    OutputPath: $.Body.content[0].text
                    End: true
            ResultSelector:
              mediaPolicy.$: States.ArrayGetItem($,0)
              typo.$: States.ArrayGetItem($,1)
      DefinitionSubstitutions:
        bedrockinvokeModel_ModelId_53adbc72: >-
          arn:aws:bedrock:us-east-1:<AWSアカウントID>:application-inference-profile/rnzkca26lh29
        bedrockinvokeModel_ModelId_49ef62c9: >-
          arn:aws:bedrock:us-east-1:<AWSアカウントID>:application-inference-profile/k8popgy6bwrj
      Name: StateMachine71095795
      Type: EXPRESS
      Role: >-
        arn:aws:iam::<AWSアカウントID>:role/prd-blog-review-api-BlogReviewStateMachineRole-1JQEwHVGFeju
      Tags:
        Tags:
          - Key: stateMachine:createdBy
            Value: SAM
      Tracing:
        Enabled: true
      Logging:
        Level: ALL
        IncludeExecutionData: true
        Destinations:
          - CloudWatchLogsLogGroup:
              LogGroupArn:
                Fn::GetAtt:
                  - LogGroupa5e6f67c
                  - Arn
  LogGroupa5e6f67c:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: /aws/vendedlogs/states/StateMachine71095795-Logs

オプションで指定した通りではありますがリソース参照にDefinitionSubstitutionsが利用されており、CW Logsのロググループ定義もエクスポートされています。このままだとリソースのIDやDefinitionSubstitutionsのキー名の可読性が低いので、その辺りだけよしなに加工してやれば便利に使えそうです。

ワークフロー作成に利用した元のSAMテンプレート

ワークフロー作成に利用した元のSAMテンプレートは以下です。推論プロファイルやコスト配分タグの設定などブログ執筆時から少しアップデートされています。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Parameters:
  Environment:
    Type: String
    Default: dev
    AllowedValues:
      - dev
      - prd
Globals:
  Api:
    TracingEnabled: true
    PropagateTags: true
  Function:
    PropagateTags: true
    Tags:
      CmBillingGroup: !Sub ${Environment}-blog-review
Resources:
  HaikuProfile:
    Type: AWS::Bedrock::ApplicationInferenceProfile
    Properties:
      InferenceProfileName: !Sub "${Environment}-blog-review-api-haiku"
      ModelSource:
        CopyFrom: arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-haiku-20240307-v1:0
      Tags:
        - Key: CmBillingGroup
          Value: !Sub "${Environment}-blog-review-api"
  SonnetProfile:
    Type: AWS::Bedrock::ApplicationInferenceProfile
    Properties:
      InferenceProfileName: !Sub "${Environment}-blog-review-api-sonnet"
      ModelSource:
        CopyFrom: arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0
      Tags:
        - Key: CmBillingGroup
          Value: !Sub "${Environment}-blog-review-api"
  Api:
    Type: AWS::Serverless::Api
    Properties:
      StageName: !Ref Environment
      DefinitionBody:
        Fn::Transform:
          Name: AWS::Include
          Parameters:
            Location: oas.yml
      Auth:
        UsagePlan:
          CreateUsagePlan: PER_API
          Description: !Sub ${Environment} ブログ自動レビューAPI用使用料プラン
          Quota:
            Limit: 1000
            Period: DAY
          Throttle:
            RateLimit: 10
            BurstLimit: 20
          UsagePlanName: !Sub ${Environment}-blog-review-usage-plan
      Tags:
        CmBillingGroup: !Sub ${Environment}-blog-review
  ApiGwRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - apigateway.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: sfn-integration
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
            - Effect: Allow
              Action:
              - states:StartSyncExecution
              Resource: '*'
  BlogReviewStateMachine:
    Type: AWS::Serverless::StateMachine
    Properties:
      Name: !Sub "${Environment}-blog-review"
      Type: EXPRESS
      DefinitionUri: blog-review.asl.yaml
      DefinitionSubstitutions:
        Environment: !Ref Environment
        SonnetProfileArn: !GetAtt SonnetProfile.InferenceProfileArn
        HaikuProfileArn: !GetAtt HaikuProfile.InferenceProfileArn
      Role: !GetAtt BlogReviewStateMachineRole.Arn
      Tracing:
        Enabled: true
      Logging:
        Level: ALL
        IncludeExecutionData: True
        Destinations:
          - CloudWatchLogsLogGroup:
              LogGroupArn: !GetAtt BlogReviewStateMachineLog.Arn
  BlogReviewStateMachineLog:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName : !Sub "/aws/states/${Environment}-blog-review-api"
      RetentionInDays: 30
  BlogReviewStateMachineRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - states.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/CloudWatchLogsFullAccess
      Policies:
        - PolicyName: bedrock
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
            - Effect: Allow
              Action:
              - bedrock:InvokeModel
              Resource: '*'

読み込んでいるaslファイルの定義は以下の通りです。

---
Comment: (${Environment}) DevIOのブログをレビューするステートマシン
StartAt: Parallel
States:
  Parallel:
    Type: Parallel
    End: true
    Branches:
    - StartAt: ReviewBlogMediaPolicy
      States:
        ReviewBlogMediaPolicy:
          Type: Task
          Resource: arn:aws:states:::bedrock:invokeModel
          Parameters:
            ModelId: ${HaikuProfileArn}
            Body:
              anthropic_version: bedrock-2023-05-31
              max_tokens: 2000
              system: |
                メディアポリシーチェック用のプロンプト
                ...略
                ```
              messages:
                - role: user
                  content:
                    - type: text
                      text.$: $.article
              temperature: 0
          OutputPath: $.Body.content[0].text
          End: true          
    - StartAt: ReviewBlogTypo
      States:
        ReviewBlogTypo:
          Type: Task
          Resource: arn:aws:states:::bedrock:invokeModel
          Parameters:
            ModelId: ${SonnetProfileArn}
            Body:
              anthropic_version: bedrock-2023-05-31
              max_tokens: 2000
              system: |
                タイポチェック用のプロンプト
                ...略
              messages:
                - role: user
                  content:
                    - type: text
                      text.$: $.article
              temperature: 0
          OutputPath: $.Body.content[0].text
          End: true
    ResultSelector:
      mediaPolicy.$: States.ArrayGetItem($,0)
      typo.$: States.ArrayGetItem($,1)

ワークフロー作成時のテンプレートとエクスポートされたテンプレートを見比べるとCW Logsのロググループなんかはワークフローに設定されたロググループをそのままエクスポートしているわけではなさそうですね。

まとめ

簡単にですがStep Functionsの熱いアップデートについて紹介しました。SAMやCFnテンプレートでStep Functionsのワークフローを作成するケースで便利に使えそうな機能です。

うまく活用して生産性向上につなげていきたいですね。

参考

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.